package tech.heptagram.staff.service.impl;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import tech.heptagram.core.common.util.JsonUtil;
import tech.heptagram.staff.mapper.DepartmentMapper;
import tech.heptagram.staff.mapper.DingtaskMapper;
import tech.heptagram.staff.mapper.WxTaskMapper;
import tech.heptagram.staff.model.Department;
import tech.heptagram.staff.model.DingtalkTask;
import tech.heptagram.staff.model.WxTask;
import tech.heptagram.staff.model.enums.JobTypeEnum;
import tech.heptagram.staff.query.DepartmentQuery;
import tech.heptagram.staff.query.DepartmentQueryBuilder;
import tech.heptagram.staff.query.DepartmentRemoveReq;
import tech.heptagram.staff.query.DepartmentReq;
import tech.heptagram.staff.service.DepartmentService;
import tech.heptagram.staff.util.AssertUtils;

/**
 * 部门Service实现类
 *
 * @author wang.yuchuan
 * @date 2018/9/10
 */
@Service
@Slf4j
public class DepartmentServiceImpl implements DepartmentService {

    @Resource
    private DepartmentMapper departmentMapper;

    @Resource
    private DingtaskMapper dingtaskMapper;

    @Resource
    private WxTaskMapper wxTaskMapper;

    @Override
    public Department getById(Integer id) {
        if (Objects.isNull(id)) {
            return null;
        }
        return departmentMapper.selectById(id);
    }

    /**
     * 根据父部门ID查询
     *
     * @param parentId 父部门ID
     * @return 部门列表信息
     */
    @Override
    public List<Department> getByParentId(Integer parentId) {
        if (Objects.isNull(parentId)) {
            return null;
        }
        return departmentMapper.selectByParentId(parentId);
    }

    @Override
    public List<Department> findByQuery(DepartmentQuery departmentQuery) {
        if (Objects.isNull(departmentQuery)) {
            return new ArrayList<>();
        }

        return departmentMapper.selectByQuery(departmentQuery);
    }

    @Override
    public List<Department> findByIds(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }

        return departmentMapper.selectByQuery(DepartmentQueryBuilder.builder().departmentIds(ids).build());
    }

    @Override
    public List<Department> findByStaffCode(String staffCode) {
        if (StringUtils.isEmpty(staffCode)) {
            return new ArrayList<>();
        }
        return departmentMapper.selectByStaffCode(staffCode);
    }

    @Override
    public Department findByDingDepartmentId(Long dingDepartmentId) {
        if (Objects.isNull(dingDepartmentId)) {
            return null;
        }
        return departmentMapper.selectByDingDepartmentId(dingDepartmentId);
    }

    @Override
    @Transactional
    public Integer save(DepartmentReq req) {
        Department department = req.getDepartment();
        AssertUtils.notNull(department, "新增部门不能为空");
        AssertUtils.notNull(department.getName(), "部门名称不能为空");
        AssertUtils.notNull(department.getParentId(), "父部门编号不能为空");
        AssertUtils.notNull(department.getParentIdStrand(), "父部门编号串不能为空");
        AssertUtils.notNull(department.getCreatedBy(), "部门创建人不能为空");
        AssertUtils.notNull(department.getModifiedBy(), "部门修改人不能为空");
        log.info("1、添加部门信息到本地");
        departmentMapper.insert(department);

        if (Objects.nonNull(req.getSync2Dingtalk()) && req.getSync2Dingtalk()) {
            log.info("2.1、添加新增部门到钉钉同步任务");
            saveDingTask(JobTypeEnum.CREATE_DEPARTMENT, department.getId());
        }
        if (Objects.nonNull(req.getSync2WorkWx()) && req.getSync2WorkWx()) {
            log.info("2.2、添加新增部门到企业微信同步任务");
            saveWxTask(JobTypeEnum.CREATE_DEPARTMENT, department.getId());
        }

        return department.getId();
    }

    @Override
    @Transactional
    public void update(DepartmentReq departmentReq) {
        Department department = departmentReq.getDepartment();
        AssertUtils.notNull(department, "修改的部门信息不能为空");
        AssertUtils.notNull(department.getId(), "部门ID不能为空");
        AssertUtils.notNull(department.getModifiedBy(), "部门修改人不能为空");
        log.info("1、修改部门信息");
        departmentMapper.update(department);

        if (Objects.nonNull(departmentReq.getSync2Dingtalk()) && departmentReq.getSync2Dingtalk()) {
            log.info("2.1、添加修改部门到钉钉同步任务");
            saveDingTask(JobTypeEnum.UPDATE_DEPARTMENT, department.getId());
        }
        if (Objects.nonNull(departmentReq.getSync2WorkWx()) && departmentReq.getSync2WorkWx()) {
            log.info("2.2、添加修改部门到企业微信同步任务");
            saveWxTask(JobTypeEnum.UPDATE_DEPARTMENT, department.getId());
        }
    }

    @Override
    @Transactional
    public void delete(DepartmentRemoveReq departmentReq) {
        AssertUtils.notNull(departmentReq.getId(), "部门ID不能为空");
        AssertUtils.notNull(departmentReq.getRemovedBy(), "部门删除人不能为空");
        log.info("1、删除部门信息");
        departmentMapper.delete(departmentReq.getId(), departmentReq.getRemovedBy());
        if (Objects.nonNull(departmentReq.getSync2Dingtalk()) && departmentReq.getSync2Dingtalk()) {
            log.info("2.1、添加删除部门到钉钉同步任务");
            saveDingTask(JobTypeEnum.DELETE_DEPARTMENT, departmentReq.getId());
        }
        if (Objects.nonNull(departmentReq.getSync2WorkWx()) && departmentReq.getSync2WorkWx()) {
            log.info("2.2、添加删除部门到企业微信同步任务");
            saveWxTask(JobTypeEnum.DELETE_DEPARTMENT, departmentReq.getId());
        }
    }

    private void saveDingTask(JobTypeEnum jobTypeEnum, Integer departmentId) {
        DingtalkTask dingTaskPo = new DingtalkTask();
        dingTaskPo.setType(jobTypeEnum.getValue());

        HashMap<String, Integer> message = new HashMap<>();
        message.put("departmentId", departmentId);
        dingTaskPo.setMessage(JsonUtil.toJson(message));

        dingtaskMapper.insert(dingTaskPo);
    }

    private void saveWxTask(JobTypeEnum jobTypeEnum, Integer departmentId) {
        WxTask wxTask = new WxTask();
        wxTask.setType(jobTypeEnum.getValue());
        HashMap<String, Integer> message = new HashMap<>();
        message.put("departmentId", departmentId);
        wxTask.setMessage(JsonUtil.toJson(message));
        wxTaskMapper.insert(wxTask);
    }
}
